/**
 * 
 */
package org.wolf.common.config;

import java.io.File;
import java.io.Serializable;
import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlType;

/**
 * @author 何小锋
 * 
 */
@XmlType
@XmlAccessorType(XmlAccessType.NONE)
public class ClusterCfg implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * 默认数据路径
	 */
	public static final String DEFAULT_DATA_DIR = System
			.getProperty("user.home")
			+ File.pathSeparator
			+ "wolf-data"
			+ File.pathSeparator;

	/**
	 * 用于存放内存数据库快照的文件夹，同时用于集群的myid文件也存在这个文件夹里
	 */
	@XmlElement
	private String dataDir;
	/**
	 * 用于单独设置transaction log的目录
	 */
	@XmlElement
	private String dataLogDir;
	/**
	 * 服务的监听端口
	 */
	@XmlElement
	private Integer clientPort = 2181;
	/**
	 * 服务绑定的地址
	 */
	@XmlElement
	private String clientPortAddress;
	/**
	 * 心跳时间，为了确保连接存在的，以毫秒为单位，最小超时时间为两个心跳时间
	 */
	@XmlElement
	private Integer tickTime = 2000;
	/**
	 * 最大并发客户端数，用于防止DOS的，默认值是10，设置为0是不加限制
	 */
	@XmlElement
	private Integer maxClientCnxns = 10;
	/**
	 * 最小的客户端session超时时间，默认值为2个tickTime，单位是毫秒
	 */
	@XmlElement
	private Integer minSessionTimeout = -1;
	/**
	 * 最大的客户端session超时时间，默认值为20个tickTime，单位是毫秒
	 */
	@XmlElement
	private Integer maxSessionTimeout = -1;
	/**
	 * 多少个心跳时间内，允许其他server连接并初始化数据，如果ZooKeeper管理的数据较大，则应相应增大这个值
	 */
	@XmlElement
	private Integer initLimit = 10;
	/**
	 * 多少个tickTime内，允许follower同步，如果follower落后太多，则会被丢弃
	 */
	@XmlElement
	private Integer syncLimit = 5;
	/**
	 * 用于选举的实现的参数<BR>
	 * <li>0为以原始的基于UDP的方式协作</li><BR>
	 * <li>1为不进行用户验证的基于UDP的快速选举</li><BR>
	 * <li>
	 * 2为进行用户验证的基于UDP的快速选举</li><BR>
	 * <li>3为基于TCP的快速选举，默认值为3</li>
	 */
	@XmlElement
	private Integer electionAlg = 3;
	/**
	 * 类型
	 */
	@XmlElement
	private String peerType = "PARTICIPANT";
	/**
	 * 服务器
	 */
	@XmlElementWrapper(name = "servers")
	@XmlElement(name = "server")
	private List<ClusterServerCfg> servers;

	public String getDataDir() {
		if (dataDir == null || dataDir.isEmpty())
			dataDir = DEFAULT_DATA_DIR;
		return dataDir;
	}

	public void setDataDir(String dataDir) {
		this.dataDir = dataDir;
	}

	public String getDataLogDir() {
		if (dataLogDir == null || dataLogDir.isEmpty())
			dataLogDir = getDataDir();
		return dataLogDir;
	}

	public void setDataLogDir(String dataLogDir) {
		this.dataLogDir = dataLogDir;
	}

	public Integer getClientPort() {
		if (clientPort == null || clientPort <= 0)
			clientPort = 2181;
		return clientPort;
	}

	public void setClientPort(Integer clientPort) {
		this.clientPort = clientPort;
	}

	public String getClientPortAddress() {
		return clientPortAddress;
	}

	public void setClientPortAddress(String clientPortAddress) {
		this.clientPortAddress = clientPortAddress;
	}

	public Integer getTickTime() {
		if (tickTime == null || tickTime <= 0)
			tickTime = 2000;
		return tickTime;
	}

	public void setTickTime(Integer tickTime) {
		this.tickTime = tickTime;
	}

	public Integer getMaxClientCnxns() {
		if (maxClientCnxns == null || maxClientCnxns < 0)
			maxClientCnxns = 10;
		return maxClientCnxns;
	}

	public void setMaxClientCnxns(Integer maxClientCnxns) {
		this.maxClientCnxns = maxClientCnxns;
	}

	public Integer getMinSessionTimeout() {
		if (minSessionTimeout == null)
			minSessionTimeout = -1;
		return minSessionTimeout;
	}

	public void setMinSessionTimeout(Integer minSessionTimeout) {
		this.minSessionTimeout = minSessionTimeout;
	}

	public Integer getMaxSessionTimeout() {
		if (maxSessionTimeout == null)
			maxSessionTimeout = -1;
		if (maxSessionTimeout < getMinSessionTimeout())
			maxSessionTimeout = getMinSessionTimeout();
		return maxSessionTimeout;
	}

	public void setMaxSessionTimeout(Integer maxSessionTimeout) {
		this.maxSessionTimeout = maxSessionTimeout;
	}

	public Integer getInitLimit() {
		if (initLimit == null || initLimit <= 0)
			initLimit = 10;
		return initLimit;
	}

	public void setInitLimit(Integer initLimit) {
		this.initLimit = initLimit;
	}

	public Integer getSyncLimit() {
		if (syncLimit == null || syncLimit <= 0)
			syncLimit = 5;
		return syncLimit;
	}

	public void setSyncLimit(Integer syncLimit) {
		this.syncLimit = syncLimit;
	}

	public Integer getElectionAlg() {
		if (electionAlg == null || electionAlg < 0 || electionAlg > 3)
			electionAlg = 3;
		return electionAlg;
	}

	public void setElectionAlg(Integer electionAlg) {
		this.electionAlg = electionAlg;
	}

	public String getPeerType() {
		if (peerType == null)
			peerType = "PARTICIPANT";
		return peerType;
	}

	public void setPeerType(String peerType) {
		this.peerType = peerType;
	}

	public List<ClusterServerCfg> getServers() {
		return servers;
	}

	public void setServers(List<ClusterServerCfg> servers) {
		this.servers = servers;
	}

}
